﻿#include "CCommonSettings.h"
#include <QMutex>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSettings>
#include <QTextCodec>

#include "CommonType.h"

namespace zl {

// function
void write_cabinet_cfg(QSettings& settings, const CabinetInfo& cfg)
{
    settings.beginGroup("CABINETINFO");
    settings.setValue("id", cfg.id.c_str());
    settings.setValue("name", cfg.name.c_str());
    settings.setValue("tag_number", cfg.tag_number);
    settings.setValue("validator_com", cfg.validator_com.c_str());
    settings.setValue("validator_baud", cfg.validator_baud);
    settings.setValue("validator_type", cfg.validator_type);
    settings.endGroup();
}

void write_platform_cfg(QSettings& settings, const PlatformConfig& cfg)
{
    settings.beginGroup("PLATFORM");
    settings.setValue("remote_addr", cfg.remote_addr.c_str());
    settings.setValue("remote_port", cfg.remote_port);
    settings.setValue("local_port", cfg.local_port);
    settings.setValue("corp_id", cfg.corp_id.c_str());
    settings.setValue("corp_name", cfg.corp_name.c_str());
    settings.setValue("site_id", cfg.site_id.c_str());
    settings.setValue("site_name", cfg.site_name.c_str());
    settings.setValue("auth_id", cfg.auth_id.c_str());
    settings.setValue("auth_name", cfg.auth_name.c_str());
    settings.setValue("payplat_uri", cfg.payplat_uri.c_str());
    settings.endGroup();
}

void write_timeout_cfg(QSettings& settings, const TimeoutItl& cfg)
{
    settings.beginGroup("TIMEOUT");
    settings.setValue("status_itl", cfg.status_itl);
    settings.setValue("heartbeat_itl", cfg.heartbeat_itl);
    settings.setValue("page_deposit_selectsize", cfg.page_deposit_selectsize);
    settings.setValue("page_deposit_setno", cfg.page_deposit_setno);
    settings.setValue("page_deposit_setpwd", cfg.page_deposit_setpwd);
    settings.setValue("page_deposit_open", cfg.page_deposit_open);
    settings.setValue("page_fetch_authpwd", cfg.page_fetch_authpwd);
    settings.setValue("page_fetch_open", cfg.page_fetch_open);
    settings.setValue("page_paytype", cfg.page_paytype);
    settings.setValue("page_payinfo", cfg.page_payinfo);
    settings.endGroup();
}

void write_payment_cfg(QSettings& settings, const PaymentConf& cfg)
{
    settings.beginGroup("PAYMENT");
    settings.setValue("enable_alipay", cfg.enable_alipay);
    settings.setValue("enable_wechatpay", cfg.enable_wechatpay);
    settings.setValue("enable_cash", cfg.enable_cash);
    settings.setValue("enable_onecode", cfg.enable_onecode);
    settings.setValue("payment_small", cfg.payment_small);
    settings.setValue("payment_medium", cfg.payment_medium);
    settings.setValue("payment_large", cfg.payment_large);
    settings.setValue("payment_extra_large", cfg.payment_extra_large);
    settings.endGroup();
}

void write_zlbase_cfg(QSettings& settings, const ZLBaseConfig& cfg)
{
    // base config
    settings.beginWriteArray("DoorControlBoard");
    for (size_t i = 0; i < cfg.dcb_list.size(); ++i)
    {
        settings.setArrayIndex(i);
        auto dcb = cfg.dcb_list[i];
        settings.setValue("index", dcb.index);
        settings.setValue("count", dcb.count);
        settings.setValue("col", dcb.col);
        settings.setValue("protocol_type", dcb.protocol_type);
        settings.setValue("type", dcb.datalinkopt.type);
        settings.setValue("is_shared", dcb.datalinkopt.is_shared);
        settings.setValue("localport", dcb.datalinkopt.localport);
        settings.setValue("remoteaddr", dcb.datalinkopt.remoteaddr.c_str());
        settings.setValue("remoteport", dcb.datalinkopt.remoteport);
        settings.setValue("com", dcb.datalinkopt.com.c_str());
        settings.setValue("baud_rate", dcb.datalinkopt.baud_rate);
        settings.setValue("flow_control", dcb.datalinkopt.flow_control);
        settings.setValue("parity", dcb.datalinkopt.parity);
        settings.setValue("stop_bits", dcb.datalinkopt.stop_bits);
        settings.setValue("character_size", dcb.datalinkopt.character_size);
        settings.setValue("timeout_coon", dcb.datalinkopt.timeout_conn);
        settings.setValue("timeout_read", dcb.datalinkopt.timeout_read);
        settings.setValue("timeout_write", dcb.datalinkopt.timeout_write);
    }
    settings.endArray();

    // layout
    settings.beginWriteArray("Layout");
    for (size_t i = 0; i < cfg.layout_list.size(); ++i)
    {
        settings.setArrayIndex(i);
        auto l = cfg.layout_list[i];
        settings.setValue("index", l.index);
        settings.setValue("typestr", l.typestr.c_str());
    }
    settings.endArray();
}

void read_cabinet_cfg(QSettings& settings, CabinetInfo& cfg)
{
    settings.beginGroup("CABINETINFO");
    cfg.id = settings.value("id", "0").toString().toStdString();
    cfg.name = settings.value("name", "").toString().toStdString();
    cfg.tag_number = settings.value("tag_number", 0).toInt();
    cfg.validator_com = settings.value("validator_com", "").toString().toStdString();
    cfg.validator_baud = settings.value("validator_baud", 9600).toInt();
    cfg.validator_type = settings.value("validator_type", 0).toInt();
    settings.endGroup();
}

void read_platform_cfg(QSettings& settings, PlatformConfig& cfg)
{
    settings.beginGroup("PLATFORM");
    cfg.remote_addr = settings.value("remote_addr", "").toString().toStdString();
    cfg.remote_port = settings.value("remote_port", 30012).toInt();
    cfg.local_port = settings.value("local_port", 30001).toInt();
    cfg.corp_id = settings.value("corp_id", "").toString().toStdString();
    cfg.corp_name = settings.value("corp_name", "").toString().toStdString();
    cfg.site_id = settings.value("site_id", "0013-0008").toString().toStdString();
    cfg.site_name = settings.value("site_name", "0013-0008").toString().toStdString();
    cfg.auth_id = settings.value("auth_id", "zhilai-web").toString().toStdString();
    cfg.auth_name = settings.value("auth_name", "zhilai-web").toString().toStdString();
    cfg.payplat_uri = settings.value("payplat_uri", "").toString().toStdString();
    settings.endGroup();
}

void read_timeout_cfg(QSettings& settings, TimeoutItl& cfg)
{
    settings.beginGroup("TIMEOUT");
    cfg.status_itl = settings.value("status_itl", 5).toInt();
    cfg.heartbeat_itl = settings.value("heartbeat_itl", 30).toInt();
    cfg.page_deposit_selectsize = settings.value("page_deposit_selectsize", 30).toInt();
    cfg.page_deposit_setno = settings.value("page_deposit_setno", 120).toInt();
    cfg.page_deposit_setpwd = settings.value("page_deposit_setpwd", 120).toInt();
    cfg.page_deposit_open = settings.value("page_deposit_open", 30).toInt();
    cfg.page_fetch_authpwd = settings.value("page_fetch_authpwd", 120).toInt();
    cfg.page_fetch_open = settings.value("page_fetch_open", 120).toInt();
    cfg.page_paytype = settings.value("page_paytype", 120).toInt();
    cfg.page_payinfo = settings.value("page_payinfo", 120).toInt();
    settings.endGroup();
}

void read_payment_cfg(QSettings& settings, PaymentConf& cfg)
{
    settings.beginGroup("PAYMENT");
    cfg.enable_alipay = settings.value("enable_alipay", 1).toInt();
    cfg.enable_wechatpay = settings.value("enable_wechatpay", 1).toInt();
    cfg.enable_cash = settings.value("enable_cash", 0).toInt();
    cfg.enable_onecode = settings.value("enable_onecode", 0).toInt();
    cfg.payment_small = settings.value("payment_small", 0).toInt();
    cfg.payment_medium = settings.value("payment_medium", 0).toInt();
    cfg.payment_large = settings.value("payment_large", 0).toInt();
    cfg.payment_extra_large = settings.value("payment_extra_large", 0).toInt();
    settings.endGroup();
}

void read_zlbase_cfg(QSettings& settings, ZLBaseConfig& cfg)
{
    // base config
    int cnt = settings.beginReadArray("DoorControlBoard");
    for (int i = 0; i < cnt; ++i)
    {
        settings.setArrayIndex(i);
        DoorControlBoard d;
        d.index = settings.value("index", i + 1).toInt();
        d.count = settings.value("count", 0).toInt();
        d.col = settings.value("col", 0).toInt();
        d.protocol_type = settings.value("protocol_type", 0).toInt();
        d.datalinkopt.type = settings.value("type", 0).toInt();
        d.datalinkopt.is_shared = settings.value("is_shared", 0).toInt();
        d.datalinkopt.localport = settings.value("localport", 30000).toInt();
        d.datalinkopt.remoteaddr = settings.value("remoteaddr", "").toString().toStdString();
        d.datalinkopt.remoteport = settings.value("remoteport", 30000).toInt();
        d.datalinkopt.com = settings.value("com", "").toString().toStdString();
        d.datalinkopt.baud_rate = settings.value("baud_rate", 9600).toInt();
        d.datalinkopt.flow_control = settings.value("flow_control", 0).toInt();
        d.datalinkopt.parity = settings.value("parity", 0).toInt();
        d.datalinkopt.stop_bits = settings.value("stop_bits", 0).toInt();
        d.datalinkopt.character_size = settings.value("character_size", 8).toInt();
        d.datalinkopt.timeout_conn = settings.value("timeout_conn", 700).toInt();
        d.datalinkopt.timeout_read = settings.value("timeout_read", 700).toInt();
        d.datalinkopt.timeout_write = settings.value("timeout_read", 700).toInt();
        cfg.dcb_list.push_back(d);
    }
    settings.endArray();

    // layout
    cnt = settings.beginReadArray("Layout");
    for (int i = 0; i < cnt; ++i)
    {
        settings.setArrayIndex(i);
        zl::Layout l;
        l.index = settings.value("index", i + 1).toInt();
        l.typestr = settings.value("typestr", "").toString().toStdString();
        cfg.layout_list.push_back(l);
    }
    settings.endArray();
}

// default
template<class T>
int32_t CCommonSettings::ReadConfig(T& cfg, const std::string& filepath)
{
    return 0;
}

template<>
int32_t CCommonSettings::ReadConfig(ZLBaseConfig& cfg, const std::string& filepath)
{
    QTextCodec *codec = QTextCodec::codecForName("GB18030");
    QSettings settings(filepath.c_str(), QSettings::IniFormat);
    settings.setIniCodec(codec);
    read_zlbase_cfg(settings, cfg);

    return zl::EResult_Success;
}

template<>
int32_t zl::CCommonSettings::ReadConfig(AppConfig& cfg, const std::string& filepath)
{
    QTextCodec *codec = QTextCodec::codecForName("GB18030");
    QSettings settings(filepath.c_str(), QSettings::IniFormat);
    settings.setIniCodec(codec);
    read_cabinet_cfg(settings, cfg.cabinet);
    read_platform_cfg(settings, cfg.server);
    read_timeout_cfg(settings, cfg.timeout);
    read_payment_cfg(settings, cfg.payment);

    return zl::EResult_Success;
}

// default
template<class T>
int32_t CCommonSettings::WriteConfig(const T& cfg, const std::string &filepath)
{
    return 0;
}

template<>
int32_t CCommonSettings::WriteConfig(const ZLBaseConfig& cfg, const std::string& filepath)
{
    QTextCodec *codec = QTextCodec::codecForName("GB18030");
    QSettings settings(filepath.c_str(), QSettings::IniFormat);
    settings.setIniCodec(codec);
    write_zlbase_cfg(settings, cfg);

    return zl::EResult_Success;
}

template<>
int32_t CCommonSettings::WriteConfig(const AppConfig& cfg, const std::string& filepath)
{
    QTextCodec *codec = QTextCodec::codecForName("GB18030");
    QSettings settings(filepath.c_str(), QSettings::IniFormat);
    settings.setIniCodec(codec);
    write_cabinet_cfg(settings, cfg.cabinet);
    write_platform_cfg(settings, cfg.server);
    write_timeout_cfg(settings, cfg.timeout);
    write_payment_cfg(settings, cfg.payment);

    return zl::EResult_Success;
}

}
